/*-------------------------------------------------------------------------
 * CLR版本:     4.0.30319.42000
 * 创建人:      song
 * 创建时间：   2024/4/9 14:47:37
 * 功 能：     场景书签功能
 *-------------------------------------------------------------------------*/

#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Overlays;
using UnityEditor.Toolbars;
using UnityEngine;
using UnityEngine.UIElements;

namespace SCore.Function.SceneBookmark
{
    [Overlay(typeof(SceneView), "Scene Bookmarks")]
    class SSceneViewBookmarkToolbarOverlay : ToolbarOverlay
    {
        SSceneViewBookmarkToolbarOverlay() : base(SceneBookmarkToolbarDropdown.ID)
        {
        }
    }

    [EditorToolbarElement(ID, typeof(SceneView))]
    class SceneBookmarkToolbarDropdown : EditorToolbarDropdown
    {
        public const string ID = "SceneBookmarkToolbarDropdown";

        public SceneBookmarkToolbarDropdown()
        {
            text = "Bookmarks";
            clicked += ShowDropdown;
            Label textElement = new Label()
            {
                text = "切换场景",
            };
            style.backgroundColor = new StyleColor(new Color(0.83f, 0.83f, 0.83f, 1.0f));
            textElement.style.fontSize = 15f;
            Add(textElement);
        }

        static void HandleMoveToBookmark(object userData)
        {
            var slot = (int)userData;
            SceneBookmarkManager.MoveToBookmark(slot);
        }

        static void HandleSetBookmark(object userData)
        {
            var slot = (int)userData;
            SceneBookmarkManager.SetBookmark(slot);
        }

        static void ShowDropdown()
        {
            var menu = new GenericMenu();

            for (var slot = 1; slot <= SceneBookmarkManager.MaxBookmarkCount; slot++)
            {
                if (SceneBookmarkManager.HasBookmark(slot))
                {
                    var sceneMark = SceneBookmarkManager.ReadFromEditorPrefs(slot);
                    string sceneGuid =
                        AssetDatabase.AssetPathToGUID(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene()
                            .path);
                    bool selfScene = sceneGuid ==
                                     sceneMark._sceneGuid;
                    menu.AddItem(new GUIContent($"{sceneMark._sceneGuid.AssetPath().FileName()}"), selfScene,
                        HandleMoveToBookmark,
                        slot);
                }
                else
                {
                    menu.AddItem(new GUIContent($"not sbookmark{slot}"), false, null,
                        slot);
                }
            }

            menu.AddSeparator(string.Empty);

            for (var slot = 1; slot <= SceneBookmarkManager.MaxBookmarkCount; slot++)
            {
                menu.AddItem(new GUIContent($"Save SceneMark {slot} &#{slot}"), false, HandleSetBookmark, slot);
            }

            menu.ShowAsContext();
        }
    }


    public static class SceneBookmarkManager
    {
        public class SceneViewBookmark
        {
            public string _sceneGuid;

            public SceneViewBookmark(string sceneGuid)
            {
                _sceneGuid = sceneGuid;
            }
        }

        public const int MaxBookmarkCount = 6;

        public static bool HasBookmark(int slot)
        {
            var key = GetEditorPrefsKey(slot);
            return EditorPrefs.HasKey(key);
        }

        public static void MoveToBookmark(int slot)
        {
            var bookmark = ReadFromEditorPrefs(slot);
            if (bookmark != null)
            {
                UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
                    AssetDatabase.GUIDToAssetPath(bookmark._sceneGuid));
            }
        }

        public static void SetBookmark(int slot)
        {
            var scene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene();
            var sceneGUID = scene.path.AssetGuid();
            for (var index = 1; index <= MaxBookmarkCount; index++)
            {
                if (HasBookmark(index))
                {
                    var showBookmark = ReadFromEditorPrefs(index);
                    if (showBookmark._sceneGuid == sceneGUID)
                    {
                        EditorPrefs.DeleteKey(GetEditorPrefsKey(index));
                    }
                }
            }

            var bookmark = new SceneViewBookmark(sceneGUID);
            WriteToEditorPrefs(slot, bookmark);
        }

        static string GetEditorPrefsKey(int slot)
        {
            return "sceneBookmark" + slot;
        }

        public static SceneViewBookmark ReadFromEditorPrefs(int slot)
        {
            var key = GetEditorPrefsKey(slot);
            var json = EditorPrefs.GetString(key);
            return JsonUtility.FromJson<SceneViewBookmark>(json);
        }

        static void WriteToEditorPrefs(int slot, SceneViewBookmark bookmark)
        {
            var key = GetEditorPrefsKey(slot);
            var json = JsonUtility.ToJson(bookmark);
            EditorPrefs.SetString(key, json);
        }
    }
}

#endif